package uk.co.droidinactu.sony.prst1.home;

import java.util.Date;
import java.util.List;

import uk.co.droidinactu.inlibrislibertas.db.DatabaseController;
import uk.co.droidinactu.inlibrislibertas.model.ImportProgressObject;
import uk.co.droidinactu.sony.prst1.home.data.Book;
import uk.co.droidinactu.sony.prst1.home.data.DataModel;
import uk.co.droidinactu.sony.prst1.home.view.ApplicationsActivity;
import uk.co.droidinactu.sony.prst1.home.view.BooksActivity;
import uk.co.droidinactu.sony.prst1.home.view.CollectionsActivity;
import uk.co.droidinactu.sony.prst1.home.view.HorizontialListView;
import uk.co.droidinactu.sony.prst1.home.view.Page2Activity;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.BaseColumns;
import android.text.format.DateFormat;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RemoteViews;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;

public final class SonyPrsT1HomeActivity extends Activity implements OnItemSelectedListener, OnClickListener {
    private static final int ACTIVITY_EDIT_PREFERENCES = 8192;

    private static final int[] bookColsMapTo = new int[] { R.id.book_grid_item_img, R.id.book_grid_item_title,
            R.id.book_grid_item_author };
    private static final String[] bookColumns = new String[] { BaseColumns._ID, Book.COLUMN_NAME_TITLE,
            Book.COLUMN_NAME_AUTHOR, };

    private static final int IMPORT_NOTIFICATION_ID = 42;

    public static final String LOG_TAG = "SonyPrsT1HomeActivity";

    private static final int MENU_PREFERENCES = 1;
    private static final int MENU_SETTINGS = 2;
    private static final int NUMBER_BOOKS_ON_SHELF = 3;

    private Button btnApps;
    private Button btnBooks;
    private Button btnCollections;
    private Button btnNextPage;
    private int collection1Start = 0;
    private int collection2Start = 0;
    private int currentlyReadingStart = 0;
    private Cursor cursrCollcnts1;
    private Cursor cursrCollcnts2;
    private Cursor cursrCurrentRead;
    private DataModel dataModel;
    private uk.co.droidinactu.inlibrislibertas.model.CalibreDataModel dataModelCalibre;
    public final Handler handler = new Handler() {
        @Override
        public void handleMessage(final Message msg) {
            final ImportProgressObject currProgressObj = (ImportProgressObject) msg.obj;
            notification.contentView.setProgressBar(R.id.status_progress, currProgressObj.totalNbrBooks,
                    currProgressObj.currentBooksRead, false);
            notificationManager.notify(SonyPrsT1HomeActivity.IMPORT_NOTIFICATION_ID, notification);
        }
    };
    private ImageView imgBtnCollection1Next;
    private ImageView imgBtnCollection1Prev;
    private ImageView imgBtnCollection2Next;
    private ImageView imgBtnCollection2Prev;
    private ImageView imgBtnCurrentReadNext;
    private ImageView imgBtnCurrentReadPrev;
    private final AsyncTask<DatabaseController, Integer, Integer> importBooksThread = new AsyncTask<DatabaseController, Integer, Integer>() {
        @Override
        protected Integer doInBackground(final DatabaseController... arg0) {
            try {
                dataModelCalibre.importCalibreMetadata(handler);
            } catch (final Exception e) {
                Toast.makeText(SonyPrsT1HomeActivity.this,
                        SonyPrsT1HomeActivity.this.getString(R.string.error_reading_in_book_metadata),
                        Toast.LENGTH_LONG);
            }
            return 0;
        }

        @Override
        protected void onPostExecute(final Integer result) {
            SonyPrsT1HomeActivity.this.progressIndicatorHide();
            super.onPostExecute(result);
        }

        @Override
        protected void onProgressUpdate(final Integer... values) {
            super.onProgressUpdate(values);
        }
    };
    private TextView lblClock;
    private TextView lblCollection1;
    private TextView lblCollection2;
    private TextView lblCurrentRead;
    private SimpleCursorAdapter listAdapterCollectns1;
    private SimpleCursorAdapter listAdapterCollectns2;
    private SimpleCursorAdapter listAdapterCurrentRead;
    private HorizontialListView listviewCollectns1;
    private HorizontialListView listviewCollectns2;
    private HorizontialListView listviewCurrentRead;
    private Notification notification;
    private NotificationManager notificationManager;

    @Override
    protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        switch (requestCode) {
        case ACTIVITY_EDIT_PREFERENCES:
            updateCurrentlyReading();
            updateCollectionlist1();
            updateCollectionlist2();
            break;
        default:
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    @Override
    public void onClick(final View v) {
        if (v.getTag().equals("apps")) {
            startActivity(new Intent(this, ApplicationsActivity.class));
        } else if (v.getTag().equals("collections")) {
            startActivity(new Intent(this, CollectionsActivity.class));
        } else if (v.getTag().equals("books")) {
            startActivity(new Intent(this, BooksActivity.class));
        } else if (v.getTag().equals("nextpage")) {
            startActivity(new Intent(this, Page2Activity.class));
        } else if (v.getTag().equals("next_currnt_read")) {
            currentlyReadingStart = currentlyReadingStart + NUMBER_BOOKS_ON_SHELF;
            updateCurrentlyReading();
        } else if (v.getTag().equals("prev_currnt_read")) {
            currentlyReadingStart = currentlyReadingStart - NUMBER_BOOKS_ON_SHELF;
            if (currentlyReadingStart < 0) {
                currentlyReadingStart = 0;
            }
            updateCurrentlyReading();
        } else if (v.getTag().equals("next_collection1")) {
            collection1Start = collection1Start + NUMBER_BOOKS_ON_SHELF;
            updateCollectionlist1();
        } else if (v.getTag().equals("prev_collection1")) {
            collection1Start = collection1Start - 3;
            if (collection1Start < 0) {
                collection1Start = 0;
            }
            updateCollectionlist1();
        } else if (v.getTag().equals("next_collection2")) {
            collection2Start = collection2Start + NUMBER_BOOKS_ON_SHELF;
            updateCollectionlist2();
        } else if (v.getTag().equals("prev_collection2")) {
            collection2Start = collection2Start - NUMBER_BOOKS_ON_SHELF;
            if (collection2Start < 0) {
                collection2Start = 0;
            }
            updateCollectionlist2();
        }
        updateCurrentTime();
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.page1);

        btnNextPage = (Button) findViewById(R.id.page1_btn_nextpage);
        btnCollections = (Button) findViewById(R.id.page1_btn_collections);
        btnApps = (Button) findViewById(R.id.page1_btn_apps);
        btnBooks = (Button) findViewById(R.id.page1_btn_books);
        lblClock = (TextView) findViewById(R.id.page1_text_clock);

        lblCurrentRead = (TextView) findViewById(R.id.page1_text_currently_reading_lbl);
        lblCollection1 = (TextView) findViewById(R.id.page1_text_collection1_lbl);
        lblCollection2 = (TextView) findViewById(R.id.page1_text_collection2_lbl);

        listviewCurrentRead = (HorizontialListView) findViewById(R.id.page1_current_reading);
        listviewCollectns1 = (HorizontialListView) findViewById(R.id.page1_collections_list1);
        listviewCollectns2 = (HorizontialListView) findViewById(R.id.page1_collections_list2);

        imgBtnCurrentReadNext = (ImageView) findViewById(R.id.page1_btn_next_currnt_read);
        imgBtnCurrentReadPrev = (ImageView) findViewById(R.id.page1_btn_prev_currnt_read);

        imgBtnCollection1Next = (ImageView) findViewById(R.id.page1_btn_next_collection1);
        imgBtnCollection1Prev = (ImageView) findViewById(R.id.page1_btn_prev_collection1);

        imgBtnCollection2Next = (ImageView) findViewById(R.id.page1_btn_next_collection2);
        imgBtnCollection2Prev = (ImageView) findViewById(R.id.page1_btn_prev_collection2);

        btnNextPage.setOnClickListener(this);
        btnApps.setOnClickListener(this);
        btnBooks.setOnClickListener(this);
        btnCollections.setOnClickListener(this);

        imgBtnCurrentReadNext.setOnClickListener(this);
        imgBtnCurrentReadPrev.setOnClickListener(this);

        imgBtnCollection1Next.setOnClickListener(this);
        imgBtnCollection1Prev.setOnClickListener(this);

        imgBtnCollection2Next.setOnClickListener(this);
        imgBtnCollection2Prev.setOnClickListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(0, MENU_SETTINGS, 0, R.string.menu_settings).setIcon(android.R.drawable.ic_menu_preferences);
        menu.add(0, MENU_PREFERENCES, 0, R.string.menu_preferences).setIcon(android.R.drawable.ic_menu_preferences);

        return true;
    }

    @Override
    public void onItemSelected(final AdapterView<?> av, final View v, final int pos, final long id) {
        dataModel.launchBook(this, id);
    }

    @Override
    public void onNothingSelected(final AdapterView<?> arg0) {
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
        case MENU_PREFERENCES:
            startActivityForResult(new Intent(this, EditPreferences.class), ACTIVITY_EDIT_PREFERENCES);
            break;
        case MENU_SETTINGS:
            startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
            break;
        default:
            return super.onOptionsItemSelected(item);
        }
        return true;
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (dataModel == null) {
            dataModel = new DataModel(this);
        }
        if (dataModelCalibre == null) {
            // dataModelCalibre = new uk.co.droidinactu.inlibrislibertas.model.DataModel(this);
        }

        Cursor tmpCursor = dataModel.getBooks(this);
        final long nbrBooks = tmpCursor.getCount();
        tmpCursor.close();
        tmpCursor = dataModel.getCollections(this);
        final long nbrCollections = tmpCursor.getCount();
        tmpCursor.close();

        final PackageManager manager = getPackageManager();
        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);

        btnApps.setText(String.format(getResources().getString(R.string.page1_Apps), "" + apps.size()));
        btnBooks.setText(String.format(getResources().getString(R.string.page1_Books), "" + nbrBooks));
        btnCollections
                .setText(String.format(getResources().getString(R.string.page1_Collections), "" + nbrCollections));

        updateCurrentlyReading();
        updateCollectionlist1();
        updateCollectionlist2();

        updateCurrentTime();
    }

    private void progressIndicatorHide() {
        try {
            final NotificationManager notificationManager = (NotificationManager) getApplicationContext()
                    .getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.cancel(IMPORT_NOTIFICATION_ID);
        } catch (final Exception e) {
        }
    }

    private void progressIndicatorShow() {
        // configure the notification
        notification = new Notification(R.drawable.application_icon,
                this.getString(R.string.notification_importing_msg), System.currentTimeMillis());
        notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
        notification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.import_progress);

        final Intent notificationIntent = new Intent(this, SonyPrsT1HomeActivity.class);
        notification.contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

        notification.contentView.setImageViewResource(R.id.status_icon, R.drawable.ic_menu_upload);
        notification.contentView.setTextViewText(R.id.status_text, this.getString(R.string.notification_importing_msg));
        notification.contentView.setProgressBar(R.id.status_progress, 100, 0, false);

        // then add it to the NotificationManager
        notificationManager = (NotificationManager) getApplicationContext().getSystemService(
                Context.NOTIFICATION_SERVICE);
        notificationManager.notify(IMPORT_NOTIFICATION_ID, notification);
    }

    private void setupList(final HorizontialListView listview, final SimpleCursorAdapter listAdapter, final Cursor cursr) {
        if ((cursr == null) || ((cursr != null) && (cursr.getCount() == 0))) {
            Toast.makeText(this, "No books available", Toast.LENGTH_LONG);
        } else {
            listview.setOnItemSelectedListener(this);
            listAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
                @Override
                public boolean setViewValue(final View view, final Cursor cursor, final int columnIndex) {
                    boolean retval = false;
                    final int idColIndex = cursor.getColumnIndexOrThrow(BaseColumns._ID);
                    final int thumbColIndex = cursor.getColumnIndexOrThrow(Book.COLUMN_NAME_THUMBNAIL);

                    if (columnIndex == idColIndex) {
                        try {
                            final ImageView coverImg = (ImageView) view;
                            final String thumbnailFilename = cursor.getString(thumbColIndex);
                            final Bitmap bitmap = dataModel.getCoverImg(SonyPrsT1HomeActivity.this, thumbnailFilename);
                            coverImg.setImageDrawable(new BitmapDrawable(bitmap));
                            retval = true;
                        } catch (final Exception e) {
                        }
                        retval = true;
                    }
                    return retval;
                }
            });
            listview.setAdapter(listAdapter);
            startManagingCursor(cursr);
        }
    }

    private void updateCollectionlist1() {
        try {
            cursrCollcnts1 = dataModel.getBooksInCollection(this, EditPreferences.getCollectionName1(this));
            final int nbrItems = cursrCollcnts1.getCount();
            lblCollection1.setText(EditPreferences.getCollectionName1(this)
                    + " ("
                    + (collection1Start + 1)
                    + " - "
                    + ((collection1Start + NUMBER_BOOKS_ON_SHELF) > nbrItems ? nbrItems
                            : (collection1Start + NUMBER_BOOKS_ON_SHELF)) + " of " + nbrItems + ")");
            cursrCollcnts1.close();
            cursrCollcnts1 = dataModel.getBooksInCollection(this, EditPreferences.getCollectionName1(this),
                    collection1Start, NUMBER_BOOKS_ON_SHELF);
            listAdapterCollectns1 = new SimpleCursorAdapter(this, R.layout.book_grid_item, cursrCollcnts1, bookColumns,
                    bookColsMapTo);
            setupList(listviewCollectns1, listAdapterCollectns1, cursrCollcnts1);
        } catch (final Exception e) {
        }
    }

    private void updateCollectionlist2() {
        try {
            cursrCollcnts2 = dataModel.getBooksInCollection(this, EditPreferences.getCollectionName2(this));
            final int nbrItems = cursrCollcnts2.getCount();
            lblCollection2.setText(EditPreferences.getCollectionName2(this)
                    + " ("
                    + (collection2Start + 1)
                    + " - "
                    + ((collection2Start + NUMBER_BOOKS_ON_SHELF) > nbrItems ? nbrItems
                            : (collection2Start + NUMBER_BOOKS_ON_SHELF)) + " of " + nbrItems + ")");
            cursrCollcnts2.close();
            cursrCollcnts2 = dataModel.getBooksInCollection(this, EditPreferences.getCollectionName2(this),
                    collection2Start, NUMBER_BOOKS_ON_SHELF);
            listAdapterCollectns2 = new SimpleCursorAdapter(this, R.layout.book_grid_item, cursrCollcnts2, bookColumns,
                    bookColsMapTo);
            setupList(listviewCollectns2, listAdapterCollectns2, cursrCollcnts2);
        } catch (final Exception e) {
        }
    }

    private void updateCurrentlyReading() {
        try {
            cursrCurrentRead = dataModel.getCurrentlyReading(this);
            final int nbrItems = cursrCurrentRead.getCount();
            lblCurrentRead.setText(getResources().getString(R.string.page1_currently_reading_lbl)
                    + " ("
                    + (currentlyReadingStart + 1)
                    + " - "
                    + ((currentlyReadingStart + NUMBER_BOOKS_ON_SHELF) > nbrItems ? nbrItems
                            : (currentlyReadingStart + NUMBER_BOOKS_ON_SHELF)) + " of " + nbrItems + ")");
            cursrCurrentRead.close();
            cursrCurrentRead = dataModel.getCurrentlyReading(this, currentlyReadingStart, NUMBER_BOOKS_ON_SHELF);
            listAdapterCurrentRead = new SimpleCursorAdapter(this, R.layout.book_grid_item, cursrCurrentRead,
                    bookColumns, bookColsMapTo);
            setupList(listviewCurrentRead, listAdapterCurrentRead, cursrCurrentRead);
        } catch (final Exception e) {
        }
    }

    private void updateCurrentTime() {
        lblClock.setText(DateFormat.format("kk:mm:ss", new Date()));
    }
}
